package com.ndood.admin.service.system.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.ndood.admin.core.constaints.AdminConstaints;
import com.ndood.admin.pojo.comm.dto.DataTableDto;
import com.ndood.admin.pojo.system.PermissionPo;
import com.ndood.admin.pojo.system.RolePo;
import com.ndood.admin.pojo.system.dto.RoleDto;
import com.ndood.admin.pojo.system.dto.TreeDto;
import com.ndood.admin.pojo.system.query.RoleQuery;
import com.ndood.admin.repository.system.PermissionRepository;
import com.ndood.admin.repository.system.RoleRepository;
import com.ndood.admin.service.system.SystemRoleService;
import com.ndood.core.utils.JPAUtil;

/**
 * 角色模块业务类
 * @author ndood
 */
@Service
public class SystemRoleServiceImpl implements SystemRoleService {

	@Autowired
	private RoleRepository roleDao;
	
	@Autowired
	private PermissionRepository permissionDao;
	
	@Override
	public void addRole(RoleDto dto) throws Exception {
		// Step1: 补充相关默认字段
		dto.setCreateTime(new Date());
		dto.setUpdateTime(new Date());
		
		// Step2: 保存角色
		RolePo po = new RolePo();
		List<Integer> resourceIds = dto.getResourceIds();
		List<PermissionPo> list = new ArrayList<PermissionPo>();
		for (Integer resourceId : resourceIds) {
			PermissionPo temp = new PermissionPo();
			temp.setId(resourceId);
			list.add(temp);
		}
		JPAUtil.childToFather(dto, po);
		// 设置复杂属性
		po.setPermissions(list);
		roleDao.save(po);
	}

	@Override
	public void batchDeleteRole(Integer[] ids) {
		// roleDao.deleteByIdByIds(Arrays.asList(ids));
		for (Integer id : ids) {
			roleDao.deleteById(id);
		}
	}

	@Override
	public void updateRole(RoleDto dto) throws Exception {
		// Step1: 删除旧角色值
		RolePo po = roleDao.findById(dto.getId()).get();
		
		// Step2: 保存新的值
		List<Integer> resourceIds = dto.getResourceIds();
		List<PermissionPo> list = new ArrayList<PermissionPo>();
		for (Integer resourceId : resourceIds) {
			PermissionPo temp = new PermissionPo();
			temp.setId(resourceId);
			list.add(temp);
		}
		JPAUtil.childToFather(dto, po);
		// 设置特殊属性
		po.setPermissions(list);
		roleDao.save(po);
	}
	
	@Override
	public RolePo getRole(Integer id) {
		return roleDao.findById(id).get();
	}

	@Override
	public DataTableDto pageRoleList(RoleQuery query) throws Exception {
		// Step1: 封装查询参数
		Integer pageSize = query.getLimit();
		String keywords = query.getKeywords();
		Integer pageNo = query.getPageNo();
		
		List<Sort.Order> orders = new ArrayList<Sort.Order>();
		Sort.Order order = new Sort.Order(Sort.Direction.ASC, "sort");
		orders.add(order);
		Pageable pageable = new PageRequest(pageNo, pageSize, new Sort(orders));

		// Step2: 进行复杂查询
		Page<RolePo> page = roleDao.findAll(new Specification<RolePo>() {
			@Override
			public Predicate toPredicate(Root<RolePo> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
				Predicate p = cb.conjunction();
				if (!StringUtils.isEmpty(keywords)) {
					Predicate temp = cb.or(
						cb.like(root.get("name"), "%" + keywords + "%"),
						cb.like(root.get("desc"), "%" + keywords + "%"));
					p = cb.and(p,temp);
				}
				return p;
			}
		}, pageable);
		
		// Step3: 转换成dto
		List<RoleDto> list = new ArrayList<RoleDto>();
		for (RolePo po : page.getContent()) {
			RoleDto dto = new RoleDto();
			JPAUtil.fatherToChild(po, dto);
			list.add(dto);
		}
		return new DataTableDto(list, page.getTotalElements());
	}

	@Override
	public List<TreeDto> getPermissionTree(Integer roleId) {
		// Step1: 查询出满足条件的资源，并封装成树
		List<PermissionPo> poList = permissionDao.findByOrderBySort();
		List<TreeDto> dtoList = new ArrayList<TreeDto>();
		for (PermissionPo po : poList) {
			TreeDto dto = new TreeDto();
			dto.setId(po.getId());
			String pid = po.getParent() == null ? "#" : po.getParent().getId()+"";
			dto.setParent(pid);
			dto.setText(po.getName());
			dto.setType("menu");
			Map<String,Object> state = new HashMap<String,Object>();
			state.put("selected", false);
			dto.setState(state);
			dtoList.add(dto);
		}
		// 如果角色id不存在（添加角色），则直接返回
		if(roleId==null){
			return dtoList;
		}
		
		// Step2: 将所有角色所拥有的资源选中
		RolePo role = roleDao.findById(roleId).get();
		List<PermissionPo> roList = role.getPermissions();
		for (PermissionPo ro : roList) {
			for (TreeDto dto : dtoList) {
				// 按钮类型才勾选
				if(ro.getId()==dto.getId()&&ro.getType()==3){
					dto.getState().put("selected", true);
				}
			}
		}
		return dtoList;
	}

	@Override
	public List<RoleDto> getRoles() throws Exception {
		// Step1: 查询出满足条件的资源，并封装成树
		List<RolePo> poList = roleDao.findByStatusEqualsOrderBySort(AdminConstaints.STATUS_OK);
		List<RoleDto> dtoList = new ArrayList<RoleDto>();
		for (RolePo po : poList) {
			RoleDto dto = new RoleDto();
			JPAUtil.fatherToChild(po, dto);
			dtoList.add(dto);
		}
		return dtoList;
	}

}
